package oop.ex3.filemanager;

import java.io.File;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

import oop.ex3.filemanager.exceptions.IllegalSourceDirException;

public class FMContext {
	
	//TODO you have many unneeded methods here. change it
	
	//lock for synchronization between thread
//	private final ReentrantReadWriteLock _fileRWL;
//	private final ReadLock _filesReadLock;
//	private final WriteLock _filesWriteLock;
//	
//	private final ReentrantReadWriteLock _serverRWL;
//	private final ReadLock _serverReadLock;
//	private final WriteLock _serverWriteLock;
	
	//files collection
	private TreeMap<String, FileInfo> _files;
	//servers collection
	private LinkedHashSet<InetSocketAddress> _servers;
	private String _dir;
	private int _port;
	
	/**
	 * construct a DataManager for FM. creates list of servers and list of files
	 * @param dir - directory to take files from
	 * @param ns - file of nameServrers
	 * @throws IllegalSourceDirException 
	 */
	public FMContext(LinkedHashSet<InetSocketAddress> ns, String dir, int port) 
	throws IllegalSourceDirException{
	
//		 _fileRWL = new ReentrantReadWriteLock();
//		 _filesReadLock = _fileRWL.readLock();
//		 _filesWriteLock = _fileRWL.writeLock();
//		 
//		_serverRWL = new ReentrantReadWriteLock();;
//	    _serverReadLock = _serverRWL.readLock();
//	    _serverWriteLock = _serverRWL.writeLock();
		 
		_files = new TreeMap<String, FileInfo>(); 
		extractFiles(dir);
		_servers = ns;
		_dir = dir;
		_port = port;
	}
	
	public String getDir(){
		return _dir;
	}
	
	
	/**
	 * extract all files from a given folder
	 * @param dir
	 * @throws IllegalSourceDirException 
	 */
	private void extractFiles(String dir) 
	throws IllegalSourceDirException{
		File dirName = new File(dir);
		if (!dirName.isDirectory()){
			throw new IllegalSourceDirException();
		}
		String[] filesStr = dirName.list(); 
		for (String file : filesStr){
			FileInfo fileInfo = new FileInfo(file, dir);
			_files.put(fileInfo.getFileName(), fileInfo);
		}
	}
	
	/**
	 * Provide access to files DB
	 * @return files Set
	 */
	public Set<String> getFilesNames(){
		return _files.keySet();
	}
	
	public FileInfo getFileInfo(String file){
		return _files.get(file);
	}
	
	public boolean containsFile(String key){
		return _files.containsKey(key);
	}
	
	public FileInfo removeFile(String key){
		FileInfo fileInfo = _files.get(key);
		_files.remove(key);
		return fileInfo;
	}
	
	public void addFile(String key, FileInfo value){
		_files.put(key, value);
	}
	
	/**
	 * Provide access to servers DB
	 * @return
	 */
	public LinkedHashSet<InetSocketAddress> getServersSet(){
		return _servers;
	}
	
	public void addServers(Collection<? extends InetSocketAddress> c){
		_servers.addAll(c);
	}

	public int getPort() {
		return _port;
	}
	
	
//	/**
//	 * provides files write lock
//	 * @return writeLock
//	 */
//	public WriteLock getFilesWritingLock(){
//		return _filesWriteLock;
//	}
//	
//	/**
//	 * provides files read lock
//	 * @return readLock
//	 */
//	public ReadLock getFilesReadLock(){
//		return _filesReadLock;
//	}
//	
//	/**
//	 * provides servers write lock
//	 * @return write lock
//	 */
//	public WriteLock getServersWritingLock(){
//		return _serverWriteLock;
//	}
//	
//	/**
//	 * provides servers read lock
//	 * @return read lock
//	 */
//	public ReadLock getServersReadLock(){
//		return _serverReadLock;
//	}
}
